package com.tc.report;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.tc.report.intersect.IntersectReportImpl;

public abstract class ReportAreaHandle {
	/** 报表管理器对象 */
	private IntersectReportImpl reportManage;
	/** 当前区域第一个字段对象 */
	private ReportField rootField;
	/** 当前区域字段对象集合 */
	private Map<String,ReportField> areaFieldMap = new HashMap<String,ReportField>();
	/** 当前区域一级节点值列表 */
	private List<ReportValueNote> rootNoteList = new ArrayList<ReportValueNote>();
	
	public ReportAreaHandle(){
		
	}
	
	public ReportAreaHandle(IntersectReportImpl reportManage){
		this.reportManage = reportManage;
	}
	
	/**
	 * 获取当前区域的第一个字段。
	 * @return
	 */
	public ReportField getRootField() {
		return rootField;
	}
	/**
	 * 获取字段名称对应的字段对象。
	 * @param fieldName
	 * @return
	 */
	public ReportField getReportField(String fieldName){
		return areaFieldMap.get(fieldName);
	}
	
	/**
	 * 向当前区域最后面增加一个字段。报表字段对象中必须设置前一个字段，第一个字段除外。
	 * @param reportField
	 * @throws Exception 
	 */
	public void addReportField(ReportField reportField) throws Exception{
		if(null==reportField){
			return;
		}
		String curFieldName = reportField.getFieldName();
		String prevFieldName = reportField.getPreviousFieldName();
		String nextFieldName = reportField.getNextFieldName();
		/** 前面字段为空，则说明为第一个字段
		 *  有两种情况下当前字段的前接字段为空：
		 *  1、当前字段为当前区域的第一个字段，此种情况，则当前字段的后接字段也为空,并且当前区域的字段列表为空。
		 *  2、当前字段移到当前区域的第一个字段,此种情况，则当前字段的后接字段不为空,同时原字段列表第一个字段的前接字段名称为空。
		 *  */
		if(StringUtils.isBlank(prevFieldName)){
			if(StringUtils.isNotBlank(nextFieldName)){//如果后面字段不为空,则说明将当前字段移到每一个字段。
				ReportField nextFieldObj = areaFieldMap.get(nextFieldName);
				if(null==nextFieldObj){
					throw new Exception("不存在后接字段:"+prevFieldName);
				}
				//
				String previousFieldName = nextFieldObj.getPreviousFieldName();
				if(StringUtils.isNotBlank(previousFieldName)){
					throw new Exception("当前后接字段不是原来的第一个字段:"+previousFieldName);
				}
				if(rootField==null){
					throw new Exception("原字段列表不存在首字段对象:");
				}
				if(!nextFieldName.equals(rootField.getFieldName())){
					throw new Exception("当前字段的后接字段不是原来的首字段对象:"+nextFieldName);
				}
				//设置后接字段的前接字段为当前字段名称。
				nextFieldObj.setPreviousFieldName(curFieldName);
			}else{//如果后接字段也为空，则说明当前区域字段还不存在字段。
				int fieldSize = areaFieldMap.size();//当前区域字段列表的大小。
				if(fieldSize>0){
					throw new Exception("已存在字段对象，请设置当前字段的前后接字段对象。");
				}
			}
			rootField = reportField;//将当前字段作为首字段。
		}else{
			/** 前接字段不为空,说明当前区域字段列表中存在前接字段对象 */
			ReportField prevFieldObj = areaFieldMap.get(prevFieldName);
			if(null==prevFieldObj){
				throw new Exception("不存在前驱字段:"+prevFieldName);
			}
			/** 
			 * 当前字段的前接字段不为空，
			 * 如果后接字段为空，则说明当前字段为当前区域的最后一个字段。
			 * 为区域最后一个字段的判断依据：
			 * 1、当前字段的前接字段为当前区域原字段列表中最后字段对象，此时该前接字段对象的后接字段名称为空。
			 * 如果后接字段不为空，则说明当前字段为当前区域中某个两个想念字段的中间位置。
			 */
			String preFieldNextFieldName = prevFieldObj.getNextFieldName();
			if(StringUtils.isBlank(nextFieldName)){
				if(StringUtils.isNotBlank(preFieldNextFieldName)){
					throw new Exception("最后字段的后接字段名称必须为空:"+preFieldNextFieldName);
				}
				//设置前接字段的后接字段名称为当前字段名称。
				prevFieldObj.setNextFieldName(curFieldName);
			}else{
				/**
				 * 如果当前字段的前接和后接字段都不为空，则当前字段的前接字段和后接字段在原来字段列表中必须为相邻字段。
				 * 相邻字段的判断依据：
				 * 1、当前字段的前接字段的后接字段名称必须为当前字段的后接字段名称。
				 * 2、当前字段的后接字段的前接字段名称必须为当前字段的前接字段名称。
				 * 实例：
				 *  调整前说明：
				 *  FieldName2->FeildName3,现将FieldName1字段插入FieldName2和FieldName3之间。
				 *  当前字段名称FieldName1,前接字段名称为FieldName2,后接字段名称为FieldName3
				 *  前接字段名称为：FieldName2,前接字段的后接字段必须为FieldName3.
				 *  后接字段名称为：FieldName3,后接字段的前接字段必须为FieldName2.
				 *  
				 *  调整后字段说明：
				 *  FieldName2->FieldName1->FeildName3
				 *  FieldName2字段对象的后接字段名称为FieldName1,前按字段名称不变。
				 *  FieldName1字段对象的前接字段名称为FieldName2,后接字段名称为FieldName3.
				 *  FieldName3字段对象的前接字段名称为FieldName1,后接字段名称不变。
				 */
				ReportField nextFieldObj = areaFieldMap.get(nextFieldName);
				if(null==nextFieldObj){
					throw new Exception("不存在后接字段:"+prevFieldName);
				}
				if(StringUtils.isBlank(preFieldNextFieldName)){
					throw new Exception("当前字段的前接字段的后接字段名称必须不为空！");
				}
				if(!preFieldNextFieldName.equals(nextFieldName)){
					throw new Exception("当前字段的前接字段的后接字段名称必须为当前字段的后接字段名称！");
				}
				String nextFieldPrevFieldName = nextFieldObj.getPreviousFieldName();				
				if(!prevFieldName.equals(nextFieldPrevFieldName)){
					throw new Exception("当前字段的后接字段的前接字段名称必须为当前字段的前接字段名称");
				}
				//设置前接字段的后接字段名称为当前字段名称。//FieldName2字段对象的后接字段名称设置为FieldName1.
				prevFieldObj.setNextFieldName(curFieldName);
				//设置当前字段的后接字段的前按字段名称为当前字段名称。//FeildName3字段对象的前接字段名称设置为FieldName1.
				nextFieldObj.setPreviousFieldName(curFieldName);				
			}
		}
		//将当前字段加入当前区域字段列表中。
		areaFieldMap.put(curFieldName, reportField);
	}
	
	/**
	 * 获取当前区域的字段大小。
	 * @return
	 */
	public int getAreaFieldSize(){
		return this.areaFieldMap.size();
	}
	/**
	 * 计算当前区域的最大纵向跨度。
	 * @return
	 */
	public abstract int getMaxColSpan();
	/**
	 * 计算当前区域的最大行向跨度。
	 * @return
	 */
	public abstract int getMaxRowSpan();
	
	/**
	 * 加载
	 * @param queryResultList
	 */
	public void loadQueryResult(List<Map<String, Object>> queryResultList) throws Exception {
		ReportField rootField = this.getRootField();//首字段
		if(queryResultList==null||queryResultList.size()==0){
			throw new Exception("查询结果集不能为空。");
		}
		String fieldName = rootField.getFieldName();
		int orderIndex=1;
		/**
		 * 将查询结果集按首字段的值进行分类存放。
		 */
		Map<String,ReportValueNote> valueNoteMap = new HashMap<String,ReportValueNote>();
		Map<String, Object> fieldDict = rootField.getFieldDict();//当前字段的字典表。
		for(Map<String,Object> queryResult:queryResultList){
			Map<String,Object> resultRow = new HashMap<String,Object>();
			resultRow.putAll(queryResult);
			String fieldValue = StringUtils.objToString(queryResult.get(fieldName));
			ReportValueNote valueNote = valueNoteMap.get(fieldValue);
			String dcitName = fieldValue;
			if (fieldDict != null) {
				dcitName = fieldDict.get(fieldValue) == null ? fieldValue : (String) fieldDict.get(fieldValue);
			}
			if(valueNote==null){
				valueNote=new ReportValueNote(this);
				valueNote.setCode(fieldValue);
				valueNote.setFieldName(fieldName);
				valueNote.setReportField(rootField);
				valueNote.setParentCode("");
				valueNote.setLevel(1);//从1开始
				valueNote.setOrderNo(orderIndex++);
				valueNoteMap.put(fieldValue, valueNote);//加入当前值列表。
				rootNoteList.add(valueNote);
			}
			resultRow.put(fieldName, dcitName);//将当前行对应字段的值转换成字典项名称。
			valueNote.getResultList().add(resultRow);
			valueNote.addQueryResult(queryResult);//将当前行结果集加入该值节点中。
		}
		/**
		 * 循环首字段的下个字段。
		 */
		for(ReportValueNote valueNote:rootNoteList){
			valueNote.loadQueryResult();
		}
	}
	
	public List<ReportValueNote> getRootNoteList() {
		return rootNoteList;
	}

	/**
	 * 处理当前区域的值列表
	 * @return
	 * @throws Exception
	 */
	public abstract List<List<DnCell>> dealAreaDataValue(List<List<DnCell>> resultList) throws Exception;
	
	/**
	 * 按默认连接符输出字段列表。
	 * @return
	 */
	public String outFieldList(){
		return getNextFieldName(this.rootField,"->");
	}
	/**
	 * 按指定连接符输出字段列表。
	 * @return
	 */
	public String outFieldList(String splitFlag){
		return getNextFieldName(this.rootField,splitFlag);
	}
	
	/**
	 * 测试使用，输出字段顺序。
	 * @param fieldObj
	 * @return
	 */
	private String getNextFieldName(ReportField fieldObj,String split){
		String names = fieldObj.getFieldName();
		String nextFieldName = fieldObj.getNextFieldName();
		if(StringUtils.isBlank(nextFieldName)){
			return names;
		}else{
			ReportField nextObj = this.areaFieldMap.get(nextFieldName);
			if(nextObj==null)return names;
			return names+=split+this.getNextFieldName(nextObj,split);
		}
	}

	public IntersectReportImpl getReportManage() {
		return reportManage;
	}

	public void setReportManage(IntersectReportImpl reportManage) {
		this.reportManage = reportManage;
	}
	
}
